package com.rtsapp.server.logger.format;

import com.rtsapp.server.logger.spi.LogEvent;
import com.rtsapp.server.logger.spi.LogLog;

import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

/**
 * 消息的格式化
 * 线程安全的
 */
public class MessageFormat implements ILogFormat {

    /**
     * 定义成静态的, 只要格式一样, 不需要有两个不一样的LogStringFormat对象
     * 日志格式化消息对象
     */
    private static final ConcurrentMap<String, LogStringFormat> stringFormatConcurrentMap = new ConcurrentHashMap<>();


    @Override
    public void format(StringBuilder sb, LogEvent e) {

        if( e.getParams() != null && e.getParams().length > 0 ){
            appendFormatLog( sb, e.getLogFomat(), e.getParams() );
        }else{
            sb.append( e.getLogFomat() );
        }

        if( e.getEx() != null ){
            StackTrace.getStackTrace( sb, e.getEx() );
        }

    }

    private void appendFormatLog(StringBuilder sb, String logFomat, Object[] params) {

        LogStringFormat stringFormat =  stringFormatConcurrentMap.get(logFomat);
        if( stringFormat == null ){
            stringFormat = new LogStringFormat( logFomat );
            LogStringFormat oldFormat =  stringFormatConcurrentMap.putIfAbsent(logFomat, stringFormat);
            if( oldFormat != null ){
                stringFormat = oldFormat;
            }
        }


        if( stringFormat.getParamCount() == params.length ){
            stringFormat.format( sb, params );
        }else{
            LogLog.error( "日志消息的占位符个数和实际参数个数不一致, 消息=" +logFomat + ", 占位符个数=" +  stringFormat.getParamCount() + ", 参数个数=" + params.length  );
            stringFormat.format( sb , logFomat );
        }


    }


}
